package com.xuelang.pipeline.entry.resource;

import com.xuelang.pipeline.app.resource.ClusterService;
import com.xuelang.pipeline.app.resource.DynamicPodService;
import com.xuelang.pipeline.app.resource.EnvironmentService;
import com.xuelang.pipeline.app.resource.SpaceService;
import com.xuelang.pipeline.app.resource.request.PodListRequest;
import com.xuelang.pipeline.app.resource.request.PodLogRequest;
import com.xuelang.pipeline.app.resource.util.TektonUtil;
import com.xuelang.pipeline.client.common.constant.Constant;
import com.xuelang.pipeline.client.common.result.ApiResult;
import com.xuelang.pipeline.client.common.util.BizAssert;
import com.xuelang.pipeline.client.common.vo.PipelineProperties;
import com.xuelang.pipeline.client.resource.IPodService;
import com.xuelang.pipeline.client.resource.dto.*;
import com.xuelang.pipeline.entry.common.DynamicFeignTemplate;
import io.kubernetes.client.openapi.models.V1PodList;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import jakarta.validation.Valid;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * Pod服务web控制类-动态切换url
 *
 * @author xiwen.zxg
 * @since 2024/5/28
 */
@Slf4j
@RestController
@RequestMapping("/dynamic-pod")
public class DynamicPodController extends DynamicFeignTemplate<DynamicPodService> implements IPodService {

    @Autowired
    EnvironmentService environmentService;
    @Autowired
    SpaceService spaceService;
    @Autowired
    ClusterService clusterService;

    @Override
    public ApiResult<List<PodListDTO>> list(@RequestBody @Valid PodListVO podListVO) {
        EnvironmentDTO environmentDTO = environmentService.query(podListVO.getEnvironmentUuid());
        BizAssert.notNull(environmentDTO, "环境不存在");
        BizAssert.notEmpty(environmentDTO.getSpaceUuid(), "请配置环境所属交付空间.");
        SpaceDTO spaceDTO = spaceService.query(environmentDTO.getSpaceUuid());
        BizAssert.notNull(spaceDTO, "交付空间不存在");
        BizAssert.notEmpty(environmentDTO.getSpaceUuid(), "请配置交付空间所属集群.");
        ClusterDTO clusterDTO = clusterService.query(spaceDTO.getClusterUuid());
        BizAssert.notNull(clusterDTO, "集群不存在");
        BizAssert.notEmpty(clusterDTO.getKubeConfig(), "请配置集群凭证.");

        PodListRequest podListRequest = new PodListRequest();
        podListRequest.setKubeConfig(clusterDTO.getKubeConfig());
        podListRequest.setNamespaceName(spaceDTO.getNamespace());
        podListRequest.setLabelName(getLabelKey(podListVO.getComponentLabel()));
        podListRequest.setPodName(podListVO.getPodName());
        Optional<PipelineProperties.Cluster> first = workerClusterMapper.stream().filter(cluster -> cluster.getUuid().equals(clusterDTO.getUuid())).findFirst();
        if (first.isPresent()) {
            ApiResult<V1PodList> podList = feignService.list(URI.create(first.get().getWorkerUrl()), podListRequest);
            List<PodListDTO> podDTOList = new ArrayList<>();
            podList.getData().getItems().forEach(v1Pod -> {
                PodListDTO podDTO = new PodListDTO();
                podDTO.setNamespaceName(spaceDTO.getNamespace());
                podDTO.setPodName(Objects.requireNonNull(v1Pod.getMetadata()).getName());
                podDTO.setCreateTime(TektonUtil.offsetDateTime2Str(Objects.requireNonNull(v1Pod.getStatus()).getStartTime()));
                podDTO.setReady(TektonUtil.getPodReadyStatus(v1Pod.getStatus().getConditions()));
                podDTO.setStatus(v1Pod.getStatus().getPhase());
                podDTOList.add(podDTO);
            });
            return ApiResult.success(podDTOList);
        }
        return notFoundClusterConfigResult();
    }

    @Override
    public ApiResult<String> log(@RequestBody @Valid PodLogVO podLogVO) {
        EnvironmentDTO environmentDTO = environmentService.query(podLogVO.getEnvironmentUuid());
        BizAssert.notNull(environmentDTO, "环境不存在");
        BizAssert.notEmpty(environmentDTO.getSpaceUuid(), "请配置环境所属交付空间.");
        SpaceDTO spaceDTO = spaceService.query(environmentDTO.getSpaceUuid());
        BizAssert.notNull(spaceDTO, "交付空间不存在");
        BizAssert.notEmpty(environmentDTO.getSpaceUuid(), "请配置交付空间所属集群.");
        ClusterDTO clusterDTO = clusterService.query(spaceDTO.getClusterUuid());
        BizAssert.notNull(clusterDTO, "集群不存在");
        BizAssert.notEmpty(clusterDTO.getKubeConfig(), "请配置集群凭证.");

        PodLogRequest podLogRequest = new PodLogRequest();
        podLogRequest.setKubeConfig(clusterDTO.getKubeConfig());
        podLogRequest.setNamespaceName(spaceDTO.getNamespace());
        podLogRequest.setLabelName(getLabelKey(podLogVO.getComponentLabel()));
        podLogRequest.setPodName(podLogVO.getPodName());
        podLogRequest.setContainer(podLogVO.getContainer());
        podLogRequest.setLimit(podLogVO.getLimit());
        Optional<PipelineProperties.Cluster> first = workerClusterMapper.stream().filter(cluster -> cluster.getUuid().equals(clusterDTO.getUuid())).findFirst();
        if (first.isPresent()) {
            return feignService.log(URI.create(first.get().getWorkerUrl()), podLogRequest);
        }
        return notFoundClusterConfigResult();
    }

    /**
     * 获取标签key
     *
     * @param componentCode
     * @return
     */
    private String getLabelKey(String componentCode) {
        return Constant.COMPONENT_LABEL_KEY_PREFIX + componentCode;
    }

}
